#ifndef AC_COMMON_GENERIC_COPY_PTR_HPP_
#define AC_COMMON_GENERIC_COPY_PTR_HPP_

template <typename T, typename Parms>
class GenericCopyPtr
{
public:
    explicit GenericCopyPtr(T* p = 0, const Parms& parms = Parms())
        : ptr_(p), parms_(parms) {}

    GenericCopyPtr(const GenericCopyPtr& other);
    GenericCopyPtr& operator = (const GenericCopyPtr& other)
    {
        assign(other.ptr_, parms_);
        return *this;
    }

    void assign(const T* other, const Parms& parms = Parms());

    void reset(T* other = 0, const Parms = Parms());

    T& operator* () const {return *ptr_;}
    T* operator-> () const {return ptr_;}
    T* get() const {return ptr_;}
    operator T* () const {return ptr_;}

    T* release() {T* tmp = ptr_; ptr_ = 0; return tmp;}

    const Parms& parms() {return parms_;}
    const Parms& parms() const {return parms_;}

    ~GenericCopyPtr();

private:
    T*      ptr_;
    Parms   parms_;
};

#endif  // AC_COMMON_GENERIC_COPY_PTR_HPP_
